package splitter

import (
	"fmt"
	"gitee.com/Billcoding/gotypes/channel"
	"log"
	"os"
	"time"
)

//file splitter struct
type FileSplitter struct {
	sourceFile  string   //Source file
	filePrefix  string   //Split file name prefix
	filePerLine int      //File line count / per
	splitCount  int      //Split file count
	splitFiles  []string //Split file array
}

//Create new file splitter
func NewFileSplitter(sourceFile, filePrefix string, filePerLine int) *FileSplitter {
	if filePrefix == "" {
		filePrefix = sourceFile
	}
	return &FileSplitter{
		sourceFile:  sourceFile,
		filePrefix:  filePrefix,
		filePerLine: filePerLine,
		splitFiles:  make([]string, 0)}
}

//Get Split file count
func (splitter *FileSplitter) SplitCount() int {
	return splitter.splitCount
}

//Get Split file names
func (splitter *FileSplitter) SplitFiles() []string {
	return splitter.splitFiles
}

//Start split
func (splitter *FileSplitter) Split() {
	start := time.Now().Unix()
	log.Printf(fmt.Sprintf("Starting file splitter [%s]", splitter.sourceFile))
	lineCount := 0
	bufferChannel := channel.NewBufferedChannel(splitter.sourceFile, 100*1024) //100KB
	var splitFile *os.File
	splitFileName := ""
	fileIndex := 0
	write := false
	for {
		buffer := bufferChannel.ReadLine()
		if buffer == nil {
			break
		}
		text := string(*buffer)
		if lineCount%splitter.filePerLine == 0 {
			write = false
			splitFileName = fmt.Sprintf("%s.%d", splitter.filePrefix, fileIndex)
			log.Printf(fmt.Sprintf("Create split file [%s]", splitFileName))
			if splitFile != nil {
				splitFile.Close()
			}
			splitFile, _ = os.Create(splitFileName)
			splitter.splitFiles = append(splitter.splitFiles, splitFileName)
			fileIndex++
		}

		if splitFile == nil {
			break
		}

		if write {
			text = "\n" + text
		}
		write = true
		splitFile.WriteString(text)
		lineCount++
	}
	if splitFile != nil {
		splitFile.Close()
	}
	end := time.Now().Unix()
	log.Printf(fmt.Sprintf("File splitter done in %ds", end-start))
}
